package com.orkasgb.framework.book;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.CDL;
import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.boot.SpringApplication;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class BigdataFrameworkApplication {

    public static void main(String[] args) {
        SpringApplication.run(BigdataFrameworkApplication.class, args);


        // String inFile = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684488161537 (1).json";
        // String outFile = "E:" + File.separator + "bookdata" + File.separator + "bookContext" + File.separator;

        String inFile1 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684488161537.json";
        String outFile1 = "E:" + File.separator + "bookdata" + File.separator + "bookContext1" + File.separator;

        // String inFile2 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684501220607 (1).json";
        // String outFile2 = "E:" + File.separator + "bookdata" + File.separator + "bookContext2" + File.separator;

        // String inFile3 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684501220607 (2).json";
        // String outFile3 = "E:" + File.separator + "bookdata" + File.separator + "bookContext3" + File.separator;

        String inFile4 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482.json";
        String outFile4 = "E:" + File.separator + "bookdata" + File.separator + "bookContext4" + File.separator;

        String inFile5 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482 (1).json";
        String outFile5 = "E:" + File.separator + "bookdata" + File.separator + "bookContext5" + File.separator;

        String inFile6 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482 (2).json";
        String outFile6 = "E:" + File.separator + "bookdata" + File.separator + "bookContext6" + File.separator;

        String inFile7 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482 (3).json";
        String outFile7 = "E:" + File.separator + "bookdata" + File.separator + "bookContext7" + File.separator;

        String inFile8 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482 (4).json";
        String outFile8 = "E:" + File.separator + "bookdata" + File.separator + "bookContext8" + File.separator;

        String inFile9 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482 (5).json";
        String outFile9 = "E:" + File.separator + "bookdata" + File.separator + "bookContext9" + File.separator;

        String inFile10 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482 (6).json";
        String outFile10 = "E:" + File.separator + "bookdata" + File.separator + "bookContext10" + File.separator;

        String inFile11 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482 (7).json";
        String outFile11 = "E:" + File.separator + "bookdata" + File.separator + "bookContext11" + File.separator;

        String inFile12 = "file:///E:" + File.separator + "bookdata" + File.separator + "this.bookChapters最终保存数据_1684504887482 (8).json";
        String outFile12 = "E:" + File.separator + "bookdata" + File.separator + "bookContext12" + File.separator;

        System.setProperty("https.protocols", "TLSv1.2");

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 12,
                30000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>());
        // threadPoolExecutor.execute(() -> {
        //     try {
        //         getInfo(inFile, outFile);
        //     } catch (IOException e) {
        //         System.out.println("执行getInfo出错了。");
        //         e.printStackTrace();
        //     }
        // });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile1, outFile1);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。");
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
        // threadPoolExecutor.execute(() -> {
        //     try {
        //         getInfo(inFile2, outFile2);
        //     } catch (IOException e) {
        //         System.out.println("执行getInfo出错了。");
        //         e.printStackTrace();
        //     }
        // });
        // threadPoolExecutor.execute(() -> {
        //     try {
        //         getInfo(inFile3, outFile3);
        //     } catch (IOException e) {
        //         System.out.println("执行getInfo出错了。");
        //         e.printStackTrace();
        //     }
        // });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile4, outFile4);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。");
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile5, outFile5);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。");
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile6, outFile6);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。");
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile7, outFile7);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。" + e.getMessage());
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile8, outFile8);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。" + e.getMessage());
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile9, outFile9);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。" + e.getMessage());
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile10, outFile10);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。" + e.getMessage());
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile11, outFile11);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。" + e.getMessage());
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });
//        threadPoolExecutor.execute(() -> {
//            try {
//                System.out.println(Thread.currentThread().getId() + "开始工作了");
//                getInfo(inFile12, outFile12);
//            } catch (IOException e) {
//                System.out.println("执行getInfo出错了。" + e.getMessage());
//                e.printStackTrace();
//            }
//            System.out.println(Thread.currentThread().getId() + "工作结束了");
//        });

//        for (int i = 4; i < 13; i++) {
//            int finalI = i;
//            threadPoolExecutor.execute(() -> {
//                try {
//                    System.out.println(Thread.currentThread().getId() + "开始工作了");
//                    jsonToCSV(finalI);
//                } catch (Exception e) {
//                    System.out.println("执行jsonToCSV出错了。");
//                    e.printStackTrace();
//                }
//                System.out.println(Thread.currentThread().getId() + "工作结束了");
//            });
//        }


    }

//	@Bean
//	public Redisson getRedisson() {
//		Config config = new Config();
//		config.useSingleServer().setDatabase(0).setAddress("redis://172.25.184.11:6381");
//		return (Redisson) Redisson.create(config);
//	}

    private static void getInfo(String inFile, String outFile) throws IOException {
        URL url = new URL(inFile);
        String string = IOUtils.toString(url, StandardCharsets.UTF_8);
        com.alibaba.fastjson.JSONArray jsonArray = com.alibaba.fastjson.JSONObject.parseArray(string);
        com.alibaba.fastjson.JSONArray jsonArray1 = new com.alibaba.fastjson.JSONArray();
        for (Object item : jsonArray) {
            JSONObject jsonObject = (JSONObject) item;
            String pageLink = (String) jsonObject.get("page_link");
            String bookId = (String) jsonObject.get("book_id");
            String bookCover = (String) jsonObject.get("book_cover");

            try {
                bookCover = getImageBase(bookCover);
            } catch (Exception e) {
                bookCover = (String) jsonObject.get("book_cover");
            }

            String bookDesc = (String) jsonObject.get("book_desc");
            JSONArray linkChapters = (JSONArray) jsonObject.get("page_link_chapters");
            for (Object chapterLinks : linkChapters) {
                JSONObject jsonObject1 = new JSONObject();
                JSONObject chapterLink = (JSONObject) chapterLinks;
                String link = ((String) chapterLink.get("link_chapters")).replace("http://localhost:8080", "https://m.biqukan8.cc");
                jsonObject1.put("page_link", pageLink);
                jsonObject1.put("book_id", bookId);
                jsonObject1.put("book_cover", bookCover);
                jsonObject1.put("page_chapter", link);
                jsonObject1.put("book_desc", StringUtils.isBlank(bookDesc) ? "" : bookDesc);
                try {
                    generatorContext(jsonObject1, link);
                } catch (Exception e) {
                    try {
                        generatorContext(jsonObject1, link);
                    } catch (Exception ex) {
                        System.out.println("重试失败 ："+ link + "错误信息：" + e.getMessage() + e.getCause());
                        e.printStackTrace();
                    }
                } finally {
                    if (jsonArray1.size() == 2000) {
                        generotrJsonFile(jsonArray1, outFile);
                    }
                }
                jsonArray1.add(jsonObject1);
            }
        }

        System.out.println(url.getFile() + "已经处理完了！");
        generotrJsonFile(jsonArray1, outFile);
    }

    private static void generatorContext(JSONObject jsonObject1, String link) throws Exception {
        Document doc = Jsoup.connect(link).get();
        Element searchInfo = doc.getElementById("chaptercontent");
        if (!Objects.isNull(searchInfo)) {
            String bookContext = searchInfo.html();
            jsonObject1.put("book_chapter_context", bookContext);
        }
    }


    private static void generotrJsonFile(com.alibaba.fastjson.JSONArray jsonArray1, String outFile) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(outFile + "bookContext最终保存数据_" + System.currentTimeMillis() + ".json");
            IOUtils.write(jsonArray1.toString(),
                    fileOutputStream,
                    StandardCharsets.UTF_8);
        } catch (IOException e) {
            System.out.println("写文件失败");
        } finally {
            try {
                if (!Objects.isNull(fileOutputStream)) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                System.out.println("关闭流出错了。");
            }
        }
        jsonArray1.clear();
    }


    private static String getImageBase(String src) throws Exception {
        // String src = "https://www.biqukan8.cc/files/article/image/14/14898/14898s.jpg";
        String suffix = src.substring(src.lastIndexOf(".") + 1);
        URL url = new URL(src);
        BufferedImage image = ImageIO.read(url);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, suffix, baos);
        byte[] baosByteArray = baos.toByteArray();
        Base64.Encoder encoder = Base64.getEncoder();
        return "data:image/jpeg;base64," + encoder.encodeToString(baosByteArray);
    }

    private static void jsonToCSV(int i) throws Exception {
        File file = new File("/home/huanzi/Desktop/bookContext/bookContext"+i+"/");
        File[] filesList = file.listFiles();
        ArrayList<String> list = new ArrayList<>();
        if (filesList != null) {
            for (File filesFile : filesList) {
                if (!filesFile.getName().endsWith(".json")) {
                    continue;
                }
                URL url = new URL("file://"+filesFile.getAbsolutePath());
                String string = IOUtils.toString(url, StandardCharsets.UTF_8);
                JSONArray jsonArray = new JSONArray(Collections.singletonList(string));
                Object preBookId = "";
                for (Object item : jsonArray) {
                    JSONObject obj = (JSONObject) item;
                    Object curBookId = obj.get("book_id");
                    if (preBookId.equals(curBookId)) {
                        obj.put("book_cover", "");
                    }
                    preBookId = curBookId;
                }
                String csv = CDL.toString(jsonArray);
                list.add("\"" + filesFile.getName() + ".csv\"");
                FileUtils.writeStringToFile(new File(filesFile.getParent() + "/" + filesFile.getName() + ".csv"), csv, StandardCharsets.UTF_8);
            }
        }

        System.out.println(list);

    }

}
